﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Plan;

namespace PlanVisualization
{
    /// <summary>
    /// Interaction logic for ScheduleControl.xaml
    /// </summary>
    public partial class ScheduleControl : UserControl
    {
        public static DependencyProperty SolutionProperty = DependencyProperty.Register("Solution", typeof(ScheduleSolution), typeof(ScheduleControl),
                                                                                 new PropertyMetadata(null));

        public ScheduleSolution Solution
        {
            get { return (ScheduleSolution)GetValue(SolutionProperty); }
            set { SetValue(SolutionProperty, value); }
        }

        public static DependencyProperty PlanProperty = DependencyProperty.Register("Plan", typeof(List<GroupPlan>), typeof(ScheduleControl),
                                                                                 new PropertyMetadata(null));

        List<GroupPlan> Plan
        {
            get { return (List<GroupPlan>)GetValue(PlanProperty); }
            set { SetValue(PlanProperty, value); }
        }

        public static DependencyProperty GroupIdProperty = DependencyProperty.Register("GroupId", typeof(int), typeof(ScheduleControl),
                                                                                 new PropertyMetadata(0));
        public int GroupId
        {
            get { return (int)GetValue(GroupIdProperty); }
            set { SetValue(GroupIdProperty, value); }
        }
        public ScheduleControl()
        {
            DataContext = this;
            InitializeComponent();
        }
        class GsDay
        {
            public IEnumerable<CustomGS> GS { get; set; }

            public int Day { get; set; }
        }
        class GroupPlan
        {
            public IEnumerable<GsDay> GS { get; set; }

            public int Group { get; set; }
        }
        internal class CustomGS
        {
            public int Room { get; set; }
            public int Subject { get; set; }
            public int TimeOfDay { get; set; }
            public int Teacher { get; set; }
        }
        void ApplySolution()
        {
            if (Solution == null)
                Plan = null;
            else
            {
                var plan = Solution.GetPlan();
                var instance = Solution.Instance;
                List<GroupPlan> groupPlans = plan.GroupBy(gs => gs.Group).
                    Select((days, gid) => new GroupPlan
                    {
                        GS = days.GroupBy(gr => gr.Time / instance.LessonsPerDay,
                        (d, gs) => new GsDay
                            {
                                GS = gs.Select(gsu => new CustomGS
                                                          {
                                                              Room = gsu.Classroom,
                                                              TimeOfDay = gsu.Time % instance.LessonsPerDay,
                                                              Subject = gsu.Subject,
                                                              Teacher = gsu.Teacher
                                                          }).SortAndFill(instance.LessonsPerDay).Select(cgs => cgs.Room < 0 ? null : cgs),
                                Day = d
                            }).Sort((a, b) => a.Day - b.Day),
                        Group = gid
                    })
                    .ToList();
                Plan = groupPlans;
            }

        }
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property == SolutionProperty)
                ApplySolution();
        }
    }
    static class EnumerableExtensions
    {
        public static IEnumerable<T> Sort<T>(this IEnumerable<T> en, Comparison<T> comp)
        {
            var list = en.ToList();
            list.Sort(comp);
            return list;
        }
        public static IEnumerable<ScheduleControl.CustomGS> SortAndFill(this IEnumerable<ScheduleControl.CustomGS> en, int totalCount)
        {
            var list = en.ToList();
            int last;
            for (int i = 0; i < totalCount; i++)
            {
                if (!list.Exists(cgs => cgs.TimeOfDay == i))
                    list.Add(new ScheduleControl.CustomGS { Room = -1, TimeOfDay = i });
            }
            list.Sort((a, b) => b.TimeOfDay - a.TimeOfDay);
            return list;
        }
    }
}
